/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package assignment1;

import java.util.StringTokenizer;
import java.util.Vector;

/**
 *
 * @author Christopher
 */
public class Expression 
{   
    public enum DatabaseObject{MIN_OBJECT, ROVER, TARGET, CELL, CONSTANT, BOOL};
    public enum DatabaseComparison{MIN_COMPARISON, EQUALS, DOES_NOT_EQUAL, GREATER_THAN, LESS_THAN};
    public enum DatabaseVariable{MIN_VARIABLE, ROVER_X, ROVER_Y, ROVER_ORIENTATION, ROVER_MOVES, ROVER_AWARE_CLEAR_PATH, ROVER_HAS_SUBGOALS, ROVER_SUBGOALS_CONTAIN_OBSTACLES, ROVER_SUBGOALS_CONTAIN_CURRENT_POSITION, ROVER_CAN_REACH_SUBGOAL, ROVER_CAN_ADD_SUBGOAL, TARGET_X, TARGET_Y, TARGET_DIRECTION, CELL_STATE, CONSTANT_INT};
    public enum ExpressionSide{EXPRESSION_LEFT, EXPRESSION_RIGHT};
    
    DatabaseObject m_leftObject;
    DatabaseObject m_rightObject;
    
    DatabaseComparison m_comparison;
    
    DatabaseVariable m_leftVariable;
    DatabaseVariable m_rightVariable;
    
    int m_leftConstant;
    int m_rightConstant;
    
    boolean m_leftBool;
    boolean m_rightBool;
    
    int m_leftCellRow;
    int m_rightCellRow;
    
    int m_leftCellColumn;
    int m_rightCellColumn;
    
    Expression()
    {
        this.setExpressionValues(Expression.DatabaseObject.MIN_OBJECT, Expression.DatabaseVariable.MIN_VARIABLE, -1, -1, 
                Expression.DatabaseComparison.MIN_COMPARISON, Expression.DatabaseObject.MIN_OBJECT, 
                Expression.DatabaseVariable.MIN_VARIABLE, -1, -1);
    }
    
    public void setExpressionValues(DatabaseObject leftObject , DatabaseVariable leftVariable, int leftCellRow, int leftCellColumn, 
                DatabaseComparison comparison, DatabaseObject rightObject, 
                DatabaseVariable rightVariable, int rightCellRow, int rightCellColumn)
    {
        m_leftObject = leftObject;
        m_rightObject = rightObject;

        m_comparison = comparison;

        m_leftVariable = leftVariable;
        m_rightVariable = rightVariable;
        
        m_leftCellRow = leftCellRow;
        m_rightCellRow = rightCellRow;

        m_leftCellColumn = leftCellColumn;
        m_rightCellColumn = rightCellColumn;
    }
    
    public void setExpressionValues(DatabaseObject leftObject, DatabaseVariable leftVariable, 
                DatabaseComparison comparison, DatabaseObject rightObject, 
                DatabaseVariable rightVariable)
    {
        m_leftObject = leftObject;
        m_rightObject = rightObject;

        m_comparison = comparison;

        m_leftVariable = leftVariable;
        m_rightVariable = rightVariable;
    }
    
    public void setExpressionValues(DatabaseObject leftObject, DatabaseVariable leftVariable,
            int leftConstant, DatabaseComparison comparison, 
            DatabaseObject rightObject, DatabaseVariable rightVariable)
    {
        m_leftObject = leftObject;
        m_rightObject = rightObject;

        m_comparison = comparison;

        m_leftVariable = leftVariable;
        m_leftConstant = leftConstant;
        m_rightVariable = rightVariable;
    }
    
    public void setExpressionValues(DatabaseObject leftObject, DatabaseVariable leftVariable,
            DatabaseComparison comparison, DatabaseObject rightObject, 
            DatabaseVariable rightVariable, int rightConstant)
    {
        m_leftObject = leftObject;
        m_rightObject = rightObject;

        m_comparison = comparison;

        m_leftVariable = leftVariable;
        m_rightVariable = rightVariable;
        m_leftConstant = rightConstant;
    }
    
    public void setExpressionValues(DatabaseObject leftObject, DatabaseVariable leftVariable,
            int leftConstant, DatabaseComparison comparison, 
            DatabaseObject rightObject, DatabaseVariable rightVariable,
            int rightConstant)
    {
        m_leftObject = leftObject;
        m_rightObject = rightObject;

        m_comparison = comparison;

        m_leftVariable = leftVariable;
        m_leftConstant = leftConstant;
        m_rightVariable = rightVariable;
        m_rightConstant = rightConstant;
    }
    
    public void populateFromString(String expressionString)
    {
        String leftSide = new String();
        String rightSide = new String();
        if(expressionString.contains("="))
        {
            m_comparison = DatabaseComparison.EQUALS;
            StringTokenizer tokenizer = new StringTokenizer(expressionString, "=");
            leftSide = tokenizer.nextToken();
            rightSide = tokenizer.nextToken();
        }
        else if(expressionString.contains("!"))
        {
            m_comparison = DatabaseComparison.DOES_NOT_EQUAL;
            StringTokenizer tokenizer = new StringTokenizer(expressionString, "!");
            leftSide = tokenizer.nextToken();
            rightSide = tokenizer.nextToken();
        }
        else if(expressionString.contains("<"))
        {
            m_comparison = DatabaseComparison.LESS_THAN;
            StringTokenizer tokenizer = new StringTokenizer(expressionString, "<");
            leftSide = tokenizer.nextToken();
            rightSide = tokenizer.nextToken();
        }
        else if(expressionString.contains(">"))
        {
            m_comparison = DatabaseComparison.GREATER_THAN;
            StringTokenizer tokenizer = new StringTokenizer(expressionString, ">");
            leftSide = tokenizer.nextToken();
            rightSide = tokenizer.nextToken();
        }
        populateSideFromString(leftSide, ExpressionSide.EXPRESSION_LEFT);
        populateSideFromString(rightSide, ExpressionSide.EXPRESSION_RIGHT);
    }
    
    private void populateSideFromString(String sideString, ExpressionSide side)
    {
        StringTokenizer tokenizer = new StringTokenizer(sideString, " ");
        String objectType = tokenizer.nextToken();
        Vector<String> sideElements = new Vector<String>();
        while(tokenizer.hasMoreTokens())
        {
            sideElements.add(tokenizer.nextToken());
        }
        
        if(objectType.equals("Rover"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftObject = DatabaseObject.ROVER;
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightObject = DatabaseObject.ROVER;
            }
            populateSidewithRoverInfo(side,sideElements);
        }
        else if(objectType.equals("Target"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftObject = DatabaseObject.TARGET;
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightObject = DatabaseObject.TARGET;
            }
            populateSidewithTargetInfo(side,sideElements);
        }
        else if(objectType.equals("Cell"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftObject = DatabaseObject.CELL;
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightObject = DatabaseObject.CELL;
            }
            populateSidewithCellInfo(side, sideElements);
        }
        else if(objectType.equals("Orientation"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftObject = DatabaseObject.CONSTANT;
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightObject = DatabaseObject.CONSTANT;
            }
            populateSidewithOrientationInfo(side, sideElements);
        }
        else if(objectType.equals("State"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftObject = DatabaseObject.CONSTANT;
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightObject = DatabaseObject.CONSTANT;
            }
            populateSidewithStateInfo(side, sideElements);
        }
        else if(objectType.equalsIgnoreCase("Constant"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftObject = DatabaseObject.CONSTANT;
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightObject = DatabaseObject.CONSTANT;
            }
            this.populateSidewithConstantInfo(side, sideElements);
        }
        else if(objectType.equalsIgnoreCase("Bool"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftObject = DatabaseObject.CONSTANT;
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightObject = DatabaseObject.CONSTANT;
            }
            this.populateSidewithBoolInfo(side, sideElements);
        }
    }
    
    private void populateSidewithOrientationInfo(ExpressionSide side, Vector<String> sideElements)
    {
        String orientationVariable = sideElements.elementAt(0);
        if(orientationVariable.equals("UP"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftConstant = Rover.Orientation.UP.ordinal();
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightConstant = Rover.Orientation.UP.ordinal();;
            }
        }
        if(orientationVariable.equals("UP_RIGHT"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftConstant = Rover.Orientation.UP_RIGHT.ordinal();
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightConstant = Rover.Orientation.UP_RIGHT.ordinal();;
            }
        }
        if(orientationVariable.equals("RIGHT"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftConstant = Rover.Orientation.RIGHT.ordinal();
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightConstant = Rover.Orientation.RIGHT.ordinal();;
            }
        }
        if(orientationVariable.equals("DOWN_RIGHT"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftConstant = Rover.Orientation.DOWN_RIGHT.ordinal();
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightConstant = Rover.Orientation.DOWN_RIGHT.ordinal();;
            }
        }
        if(orientationVariable.equals("DOWN"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftConstant = Rover.Orientation.DOWN.ordinal();
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightConstant = Rover.Orientation.DOWN.ordinal();;
            }
        }
        if(orientationVariable.equals("DOWN_LEFT"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftConstant = Rover.Orientation.DOWN_LEFT.ordinal();
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightConstant = Rover.Orientation.DOWN_LEFT.ordinal();;
            }
        }
        if(orientationVariable.equals("LEFT"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftConstant = Rover.Orientation.LEFT.ordinal();
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightConstant = Rover.Orientation.LEFT.ordinal();;
            }
        }
        if(orientationVariable.equals("UP_LEFT"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftConstant = Rover.Orientation.UP_LEFT.ordinal();
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightConstant = Rover.Orientation.UP_LEFT.ordinal();;
            }
        }
    }
    
    private void populateSidewithStateInfo(ExpressionSide side, Vector<String> sideElements)
    {
        String stateVariable = sideElements.elementAt(0);
        if(stateVariable.equalsIgnoreCase("CLEAR"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftConstant = Cell.State.CLEAR.ordinal();
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightConstant = Cell.State.CLEAR.ordinal();
            }
        }
        if(stateVariable.equalsIgnoreCase("UNKNOWN"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftConstant = Cell.State.UNKNOWN.ordinal();
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightConstant = Cell.State.UNKNOWN.ordinal();
            }
        }
        if(stateVariable.equalsIgnoreCase("OBSTACLE"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftConstant = Cell.State.OBSTACLE.ordinal();
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightConstant = Cell.State.OBSTACLE.ordinal();
            }
        }
        if(stateVariable.equalsIgnoreCase("TARGET"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftConstant = Cell.State.TARGET.ordinal();
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightConstant = Cell.State.TARGET.ordinal();
            }
        }
    }
    
    private void populateSidewithRoverInfo(ExpressionSide side, Vector<String> sideElements)
    {
        String roverVariable = sideElements.elementAt(0);
        if(roverVariable.equals("X"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftVariable = DatabaseVariable.ROVER_X;
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightVariable = DatabaseVariable.ROVER_X;
            }
        }
        if(roverVariable.equals("Y"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftVariable = DatabaseVariable.ROVER_Y;
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightVariable = DatabaseVariable.ROVER_Y;
            }
        }
        if(roverVariable.equalsIgnoreCase("ORIENTATION"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftVariable = DatabaseVariable.ROVER_ORIENTATION;
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightVariable = DatabaseVariable.ROVER_ORIENTATION;
            }
        }
        if(roverVariable.equalsIgnoreCase("MOVES"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftVariable = DatabaseVariable.ROVER_MOVES;
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightVariable = DatabaseVariable.ROVER_MOVES;
            }
        }
        if(roverVariable.equalsIgnoreCase("AWARE_CLEAR_PATH"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftVariable = DatabaseVariable.ROVER_AWARE_CLEAR_PATH;
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightVariable = DatabaseVariable.ROVER_AWARE_CLEAR_PATH;
            }
        }
        if(roverVariable.equalsIgnoreCase("has_subgoals"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftVariable = DatabaseVariable.ROVER_HAS_SUBGOALS;
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightVariable = DatabaseVariable.ROVER_HAS_SUBGOALS;
            }
        }
        if(roverVariable.equalsIgnoreCase("subgoals_contain_obstacles"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftVariable = DatabaseVariable.ROVER_SUBGOALS_CONTAIN_OBSTACLES;
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightVariable = DatabaseVariable.ROVER_SUBGOALS_CONTAIN_OBSTACLES;
            }
        }
        if(roverVariable.equalsIgnoreCase("subgoals_contain_current_position"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftVariable = DatabaseVariable.ROVER_SUBGOALS_CONTAIN_CURRENT_POSITION;
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightVariable = DatabaseVariable.ROVER_SUBGOALS_CONTAIN_CURRENT_POSITION;
            }
        }
        if(roverVariable.equalsIgnoreCase("can_reach_subgoal"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftVariable = DatabaseVariable.ROVER_CAN_REACH_SUBGOAL;
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightVariable = DatabaseVariable.ROVER_CAN_REACH_SUBGOAL;
            }
        }
        if(roverVariable.equalsIgnoreCase("can_add_subgoals"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftVariable = DatabaseVariable.ROVER_CAN_ADD_SUBGOAL;
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightVariable = DatabaseVariable.ROVER_CAN_ADD_SUBGOAL;
            }
        }
    }
    
    private void populateSidewithTargetInfo(ExpressionSide side, Vector<String> sideElements)
    {
        String targetVariable = sideElements.elementAt(0);
        if(targetVariable.equalsIgnoreCase("X"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftVariable = DatabaseVariable.TARGET_X;
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightVariable = DatabaseVariable.TARGET_X;
            }
        }
        if(targetVariable.equalsIgnoreCase("Y"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftVariable = DatabaseVariable.TARGET_Y;
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightVariable = DatabaseVariable.TARGET_Y;
            }
        }
        if(targetVariable.equalsIgnoreCase("direction"))
        {
            if(side == ExpressionSide.EXPRESSION_LEFT)
            {
                m_leftVariable = DatabaseVariable.TARGET_DIRECTION;
            }
            else if(side == ExpressionSide.EXPRESSION_RIGHT)
            {
                m_rightVariable = DatabaseVariable.TARGET_DIRECTION;
            }
        }
    }
    
    private void populateSidewithConstantInfo(ExpressionSide side, Vector<String> sideElements) {
        if(side == ExpressionSide.EXPRESSION_LEFT)
        {
            m_leftConstant = Integer.parseInt(sideElements.elementAt(0));
        }
        else if(side == ExpressionSide.EXPRESSION_RIGHT)
        {
            m_rightConstant = Integer.parseInt(sideElements.elementAt(0));
        }
    }
    
    private void populateSidewithBoolInfo(ExpressionSide side, Vector<String> sideElements) {
        if(side == ExpressionSide.EXPRESSION_LEFT)
        {
            m_leftConstant = sideElements.elementAt(0).equalsIgnoreCase("true") ? 1 : 0;
        }
        else if(side == ExpressionSide.EXPRESSION_RIGHT)
        {
            m_rightConstant = sideElements.elementAt(0).equalsIgnoreCase("true") ? 1 : 0;
        }
    }
    
    private void populateSidewithCellInfo(ExpressionSide side, Vector<String> sideElements)
    {
        String CellStateVariable = sideElements.elementAt(0);
        
        if(side == ExpressionSide.EXPRESSION_LEFT)
        {
            m_leftVariable = DatabaseVariable.CELL_STATE;
            m_leftCellColumn = Integer.parseInt(sideElements.elementAt(0));
            m_leftCellRow = Integer.parseInt(sideElements.elementAt(1));
        }
        else if(side == ExpressionSide.EXPRESSION_RIGHT)
        {
            m_rightVariable = DatabaseVariable.CELL_STATE;
            m_rightCellColumn = Integer.parseInt(sideElements.elementAt(0));
            m_rightCellRow = Integer.parseInt(sideElements.elementAt(1));
        }
    }
    
    boolean evaluate(Database database) {
        int leftValue = this.getValue(ExpressionSide.EXPRESSION_LEFT, database);
        int rightValue = this.getValue(ExpressionSide.EXPRESSION_RIGHT, database);
        return this.compareValues(leftValue, rightValue);
    }
    
    private int getValue(ExpressionSide side, Database database)
    {
        int retVal = -1;
        DatabaseObject valueObject;
        if(side == ExpressionSide.EXPRESSION_LEFT)
        {
            valueObject = m_leftObject;
        }
        else
        {
            valueObject = m_rightObject;
        }
        
        switch(valueObject)
        {
            case ROVER:
                retVal = this.getRoverValue(side, database.rover());
                break;
            case TARGET:
                retVal = this.getTargetValue(side, database);
                break;
            case CELL:
                retVal = this.getCellValue(side, database);
                break;
            case CONSTANT:
                retVal = this.getConstantValue(side);
                break;
        }
        return retVal;
    }
    
    private int getConstantValue(ExpressionSide side)
    {
        int retVal = -1;
        if(side == ExpressionSide.EXPRESSION_LEFT)
        {
            retVal = m_leftConstant;
        }
        else if(side == ExpressionSide.EXPRESSION_RIGHT)
        {
            retVal = m_rightConstant;
        }
        return retVal;
    }
            
    
    private int getRoverValue(ExpressionSide side, Rover rover)
    {
        int retVal = -1;
        DatabaseVariable roverVariable = DatabaseVariable.MIN_VARIABLE;
        if(side == ExpressionSide.EXPRESSION_LEFT)
        {
            roverVariable = m_leftVariable;
        }
        else if(side == ExpressionSide.EXPRESSION_RIGHT)
        {
            roverVariable = m_rightVariable;
        }
        switch(roverVariable)
        {
            case ROVER_X:
                retVal = rover.x();
                break;
            case ROVER_Y:
                retVal = rover.y();
                break;
            case ROVER_ORIENTATION:
                retVal = rover.orientation().ordinal();
                break;
            case ROVER_MOVES:
                retVal = rover.completedMoves();
                break;
            case ROVER_AWARE_CLEAR_PATH:
                retVal = rover.awareOfClearPath() ? 1 : 0;
                break;
            case ROVER_HAS_SUBGOALS:
                retVal = rover.hasSubgoals() ? 1 : 0;
                break;
            case ROVER_SUBGOALS_CONTAIN_OBSTACLES:
                retVal = rover.subgoalsContainObstacles() ? 1 : 0;
                break;
            case ROVER_SUBGOALS_CONTAIN_CURRENT_POSITION:
                retVal = rover.subgoalsContainCurrentPosition() ? 1 : 0;
                break;
            case ROVER_CAN_REACH_SUBGOAL:
                retVal = rover.canReachSubgoal() ? 1 : 0;
                break;
            case ROVER_CAN_ADD_SUBGOAL:
                retVal = rover.canAddSubgoal() ? 1 : 0;
                break;
        }
        return retVal;
    }
    
    private int getTargetValue(ExpressionSide side, Database database)
    {
        int retVal = -1;
        DatabaseVariable targetVariable = DatabaseVariable.MIN_VARIABLE;
        if(side == ExpressionSide.EXPRESSION_LEFT)
        {
            targetVariable = m_leftVariable;
        }
        else if(side == ExpressionSide.EXPRESSION_RIGHT)
        {
            targetVariable = m_rightVariable;
        }
        switch(targetVariable)
        {
            case TARGET_X:
                retVal = database.fullBoard().targetColumn();
                break;
            case TARGET_Y:
                retVal = database.fullBoard().targetRow();
                break;
            case TARGET_DIRECTION:
                retVal = database.rover().targetDirection().ordinal();
                break;
        }
        return retVal;
    }
    
    private int getCellValue(ExpressionSide side, Database database) //Cells are ofset from rover
    {
        int retVal = -1;
        DatabaseVariable cellVariable = DatabaseVariable.MIN_VARIABLE;
        int cellRow = -1;
        int cellColumn = -1;
        if(side == ExpressionSide.EXPRESSION_LEFT)
        {
            cellVariable = m_leftVariable;
            cellRow = m_leftCellRow + database.rover().y();
            cellColumn = m_leftCellColumn + database.rover().x();
        }
        else if(side == ExpressionSide.EXPRESSION_RIGHT)
        {
            cellVariable = m_rightVariable;
            cellRow = m_rightCellRow + database.rover().y();
            cellColumn = m_rightCellColumn + database.rover().x();
        }
        switch(cellVariable)
        {
            case CELL_STATE:
                retVal = database.discoveredBoard().cellState(cellRow, cellColumn).ordinal();
                break;
        }
        return retVal;
    }
    
    private boolean compareValues(int left, int right)
    {
        boolean retVal = false;
        switch(m_comparison)
        {
            case EQUALS:
                retVal = (left == right);
                break;
            case DOES_NOT_EQUAL:
                retVal = (left != right);
                break;
            case GREATER_THAN:
                retVal = (left > right);
                break;
            case LESS_THAN:
                retVal = (left < right);
                break;
        }
        return retVal;
    }
}
